﻿'Imports System.Windows.Forms
Imports System.Data
Imports System.Reflection

Public Module DCM_Data
    Public Function ConvertMilsecondToDateString(Milsecond As Long) As String
        Dim Hour As Double, Minute As Double, Second As Double
        Hour = Milsecond \ 3600000
        If Hour > 0 Then Milsecond -= Hour * 3600000
        Minute = Milsecond \ 60000
        If Minute > 0 Then Milsecond -= Minute * 60000
        Second = Milsecond \ 1000
        Return String.Format("{0}:{1}:{2}", Hour.ToString("00"), Minute.ToString("00"), Second.ToString("00"))
    End Function
    Public Function DataSet_寻找(ByRef DS As DataSet, TableName As String) As DataTable
        For i As Integer = 0 To DS.Tables.Count - 1
            If DS.Tables(i).TableName = TableName Then
                Return DS.Tables(i)
            End If
        Next
        Throw New Exception("无法找到:" & TableName)
    End Function
    'Public Fu
    Public Sub DataSet_替换(ByRef DS As DataSet, ByRef DT As DataTable, TableName As String)
        For i As Integer = 0 To DS.Tables.Count - 1
            If DS.Tables(i).TableName = TableName Then
                DT.TableName = TableName
                DS.Tables.RemoveAt(i)
                DS.AcceptChanges()
                DS.Tables.Add(DT)
                Return
            End If
        Next
        Throw New Exception("无法找到:" & TableName)
    End Sub
    'Public Function CheckDataTypeIs数值类型(Type_Send As Type) As Boolean
    '    If Type_Send Is GetType(Integer) Then Return True
    '    If Type_Send Is GetType(Long) Then Return True
    '    If Type_Send Is GetType(Single) Then Return True
    '    If Type_Send Is GetType(Double) Then Return True
    '    If Type_Send Is GetType(System.Decimal) Then Return True
    '    If Type_Send Is GetType(System.Int32) Then Return True
    '    If Type_Send Is GetType(System.Decimal) Then Return True
    '    If Type_Send Is GetType(System.Single) Then Return True
    '    If Type_Send Is GetType(System.Double) Then Return True
    '    If Type_Send Is GetType(System.Int64) Then Return True
    '    If Type_Send Is GetType(System.Int16) Then Return True
    '    If Type_Send Is GetType(System.UInt16) Then Return True
    '    If Type_Send Is GetType(System.UInt32) Then Return True
    '    If Type_Send Is GetType(System.UInt64) Then Return True
    '    Return False
    'End Function
    'Public Function 从DataTable列中随机抽取一条不重复的数据到数组中_fun(DV As DataView, 选择的列名 As String, 抽取的数量 As Integer) As List(Of String)
    '    Dim 存入的数据s As New List(Of String)
    '    从DataTable列中随机抽取一条不重复的数据到数组中_sub(DV, 选择的列名, 抽取的数量, 存入的数据s)
    '    Return 存入的数据s
    'End Function


    'Public Sub 从DataTable列中随机抽取一条不重复的数据到数组中_sub(DV As DataView, 选择的列名 As String, 抽取的数量 As Integer, ByRef 存入的数组s As List(Of String))
    '    Dim 不重复的数据s = Dll_ColumnNames(选择的列名, DV)
    '    从数组列表中抽取一条不重复的数据到数组中_sub(不重复的数据s, 抽取的数量, 存入的数组s)
    'End Sub
    'Public Sub 从数组列表中抽取一条不重复的数据到数组中_sub(ByRef 需要抽取的数组() As String, 抽取的数量 As Integer, ByRef 存入的数组s As List(Of String))
    '    For i As Integer = 0 To 抽取的数量
    '        If 存入的数组s.Count >= 需要抽取的数组.Count Then Exit For
    '        Do While True
    '            Dim 取出的随机数 = 随机从数组中抽取一位(需要抽取的数组)
    '            Dim 是否重复 = False
    '            For Each item In 存入的数组s
    '                If item = 取出的随机数 Then
    '                    是否重复 = True
    '                    Exit For
    '                End If
    '            Next
    '            If 是否重复 = False Then
    '                存入的数组s.Add(取出的随机数)
    '                Exit Do
    '            End If
    '        Loop
    '    Next
    'End Sub
    'Private Function 随机从数组中抽取一位(数值s() As String) As String
    '    Randomize()
    '    Dim Rindex = Rnd() * (数值s.Count - 1)
    '    Return 数值s(Rindex)
    'End Function

    'Public Function 获取DT分组多维数组(DV As DataView, ParamArray Columns() As String) As DataTable
    '    Using dt = DV.ToTable
    '        Return 获取DT分组多维数组(dt, Columns)
    '    End Using
    'End Function

    'Public Function 获取DT分组多维数组(DT As DataTable, ParamArray Columns() As String) As DataTable
    '    Dim DT_out As New DataTable
    '    For i As Integer = 0 To Columns.Count - 1
    '        DataTableColumnAdd(DT_out, Columns(i), DT.Columns(Columns(i)).DataType)
    '    Next
    '    Dim GP As System.Collections.Generic.IEnumerable(Of System.Linq.IGrouping(Of System.Object, System.Data.DataRow))
    '    Select Case Columns.Count
    '        Case 0
    '            Throw New Exception("至少一个分组")
    '        Case 1
    '            GP = DT.AsEnumerable.GroupBy(Function(g) New With {Key .c0 = g(Columns(0))})
    '        Case 2
    '            GP = DT.AsEnumerable.GroupBy(Function(g) New With {Key .c0 = g(Columns(0)), Key .c1 = g(Columns(1))})
    '            'Dim GPp = From dr In DT.AsEnumerable
    '            '   Group dr By key = New With {Key .c0 = dr(Columns(0)), Key .c1 = dr(Columns(1))} Into g = Group
    '            '   Select key.c0, key.c1
    '            'Dim GPs = GPp.ToList
    '        Case 3
    '            GP = DT.AsEnumerable.GroupBy(Function(g) New With {Key .c0 = g(Columns(0)),
    '                                                               Key .c1 = g(Columns(1)),
    '                                                               Key .c2 = g(Columns(2))})
    '        Case 4
    '            GP = DT.AsEnumerable.GroupBy(Function(g) New With {Key .c0 = g(Columns(0)),
    '                                                               Key .c1 = g(Columns(1)),
    '                                                               Key .c2 = g(Columns(2)),
    '                                                               Key .c3 = g(Columns(3))})
    '        Case 5
    '            GP = DT.AsEnumerable.GroupBy(Function(g) New With {Key .c0 = g(Columns(0)),
    '                                                               Key .c1 = g(Columns(1)),
    '                                                               Key .c2 = g(Columns(2)),
    '                                                               Key .c3 = g(Columns(3)),
    '                                                               Key .c4 = g(Columns(4))})
    '        Case 6
    '            GP = DT.AsEnumerable.GroupBy(Function(g) New With {Key .c0 = g(Columns(0)),
    '                                                               Key .c1 = g(Columns(1)),
    '                                                               Key .c2 = g(Columns(2)),
    '                                                               Key .c3 = g(Columns(3)),
    '                                                               Key .c4 = g(Columns(4)),
    '                                                               Key .c5 = g(Columns(5))})
    '        Case Else
    '            Throw New Exception("无法输出超过6位的分组")
    '    End Select
    '    Dim RValues(GP.Count - 1, Columns.Count - 1) As Object
    '    For i As Integer = 0 To GP.Count - 1
    '        Dim ndr = DT_out.NewRow
    '        For j As Integer = 0 To Columns.Count - 1
    '            Dim dr As DataRow = GP(i)(0)
    '            ndr(Columns(j)) = GP(i)(0)(Columns(j))
    '        Next
    '        DT_out.Rows.Add(ndr)
    '    Next
    '    Return DT_out
    'End Function

    Public Sub SetPrivateField设置私有变量属性(instance As Object, fieldname As String, value As Object)
        Dim flag As BindingFlags = BindingFlags.Instance Or BindingFlags.NonPublic
        Dim type As Type = instance.[GetType]()
        Dim field As FieldInfo = type.GetField(fieldname, flag)

        field.SetValue(instance, value)
    End Sub

    Public Sub List_String_Add(ByRef Lists As List(Of String), ParamArray Values() As Object)
        For i As Integer = 0 To Values.Count - 1
            Lists.Add(Values(i))
        Next
    End Sub
    Public Function Fun_将字符转化为Enum值(Value As String, Type As Type) As Object
        For Each item In [Enum].GetValues(Type)
            If item.ToString = Value Then Return item
        Next
        Throw New Exception("无法找到:" & Value)
    End Function
    Public Function Fun_将Enum转化为数组_list(Type As Type) As List(Of String)
        Dim RS As New List(Of String)
        For Each item In [Enum].GetValues(Type)
            RS.Add(item.ToString)
        Next
        Return RS
    End Function
    Public Function Fun_将Enum转化为数组(Type As Type) As String()
        Return Fun_将Enum转化为数组_list(Type).ToArray
    End Function
    Public Function Fun_根据两端取中间_从最和最右两端分析(s1, Flag_1, Flag_2) As String
        Dim Index_1 As Integer = InStr(s1, Flag_1)
        If Index_1 <= 0 Then Return ""
        Dim Index_2 As Integer = InStrRev(s1, Flag_2)
        If Index_2 <= 0 Then Return ""
        Return Mid(s1, Index_1 + 1, Index_2 - Index_1 - 1)
    End Function
    Public Function Fun_根据两端取中间_从左到右依次分析(s1, Flag_1, Flag_2) As List(Of String)
        Dim RS As New List(Of String)
        Dim Index_1 As Integer = InStr(s1, Flag_1)
        If Index_1 <= 0 Then Return RS
        s1 = Mid(s1, Index_1 + Len(Flag_1))
        Dim Index_2 As Integer = InStr(s1, Flag_2)
        Do While Index_2 > 0
            Dim This_S As String = Mid(s1, 1, Index_2 - 1)
            RS.Add(This_S)
            Dim leaveIndex As Integer = Index_2 + Len(Flag_2)
            s1 = Mid(s1, leaveIndex)
            Index_1 = InStr(s1, Flag_1)
            If Index_1 <= 0 Then Return RS
            s1 = Mid(s1, Index_1 + Len(Flag_1))
            Index_2 = InStr(s1, Flag_2)
        Loop
        Return RS
    End Function

    Public Function DCM_去掉字符串左右空格和回车换行符(str_old As String) As String
        str_old = str_old.Replace(" ", "")
        str_old = str_old.Replace(vbCr, "")
        str_old = str_old.Replace(vbLf, "")
        str_old = str_old.Replace("　", "")
        str_old = str_old.Replace(vbTab, "")
        Return str_old
    End Function
    'Public Function DCM_MessageBoxShow_OKYes(ShowString As String) As Microsoft.VisualBasic.MsgBoxResult
    '    Dim R = MsgBox(ShowString, MsgBoxStyle.YesNo)
    'End Function

    Public Function Fun_将DT列转化为数组(dt As DataTable, columnName As String) As String()
        Dim RS As New List(Of String)
        For i As Integer = 0 To dt.Rows.Count - 1
            RS.Add(DCM.CaseDBNullToString(dt.Rows(i)(columnName)))
        Next
        Return RS.ToArray
    End Function
    Public Function Fun_将DT列转化为数组(dt As DataTable) As String()
        If dt.Columns.Count <> 1 Then Throw New Exception("只传入DT时只能有一列数据!")
        Dim columnName As String = dt.Columns(0).ColumnName
        Return Fun_将DT列转化为数组(dt, columnName)
    End Function
    Public Function Fun_将DT列转化为字符串(dt As DataTable, columnName As String) As String
        Return String.Join(",", Fun_将DT列转化为数组(dt, columnName))
    End Function
    Public Function Fun_将DT列名转化为数组(dt As DataTable) As String()
        Dim rs As New List(Of String)
        For i As Integer = 0 To dt.Columns.Count - 1
            rs.Add(dt.Columns(i).ColumnName)
        Next
        Return rs.ToArray
    End Function
    Public Function Get_以数量补齐字符串(补齐的字符串 As String, 数量 As Integer) As String
        Dim RS As String = ""
        For i As Integer = 0 To 数量
            RS += 补齐的字符串
        Next
        Return RS
    End Function
    Public Function CheckDataTypeIsDataTime(Type_Send As Type) As Boolean
        If Type_Send Is GetType(DateTime) Then Return True
        Return False
    End Function
    Public Function CheckDataTypeIs数值类型(Type_Send As Type) As Boolean
        If Type_Send Is GetType(Integer) Then Return True
        If Type_Send Is GetType(Long) Then Return True
        If Type_Send Is GetType(Single) Then Return True
        If Type_Send Is GetType(Double) Then Return True
        If Type_Send Is GetType(System.Decimal) Then Return True
        If Type_Send Is GetType(System.Int32) Then Return True
        If Type_Send Is GetType(System.Decimal) Then Return True
        If Type_Send Is GetType(System.Single) Then Return True
        If Type_Send Is GetType(System.Double) Then Return True
        If Type_Send Is GetType(System.Int64) Then Return True
        If Type_Send Is GetType(System.Int16) Then Return True
        If Type_Send Is GetType(System.UInt16) Then Return True
        If Type_Send Is GetType(System.UInt32) Then Return True
        If Type_Send Is GetType(System.UInt64) Then Return True
        Return False
    End Function
    ''' <summary>
    ''' 不重复添加数据,添加成功返回true,失败返回false
    ''' </summary>
    ''' <param name="showColumns"></param>
    ''' <param name="Value"></param>
    Public Function 数组添加成员_不重复(ByRef 数组() As String, Value As String) As Boolean
        Try
            For Each item In 数组
                If item = Value Then Return False
            Next
            ReDim Preserve 数组(数组.Length)
            数组(数组.Length - 1) = Value
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function
    Public Function 数组添加成员_不重复(ByRef 数组 As List(Of String), Value As String) As Boolean
        Try
            For Each item In 数组
                If item = Value Then Return False
            Next
            数组.Add(Value)
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function
    Public Sub 数组添加成员(ByRef showColumns() As String, Value As String)
        Try
            ReDim Preserve showColumns(showColumns.Length)
            showColumns(showColumns.Length - 1) = Value
        Catch ex As Exception

        End Try
    End Sub
    Public Sub 删除数组指定列(ByRef showColumns As List(Of String), delcol As String)
        Try
            showColumns.Remove(delcol)
        Catch ex As Exception

        End Try
    End Sub
    Public Sub 删除数组指定列(ByRef showColumns As List(Of String), delcols() As String)
        Try
            For Each delcol In delcols
                Try
                    showColumns.Remove(delcol)
                Catch ex As Exception

                End Try
            Next

        Catch ex As Exception

        End Try
    End Sub
    Public Function GetDataTableAllColumnNames(DT As DataTable) As List(Of String)
        Dim RS As New List(Of String)
        For Each col As DataColumn In DT.Columns
            RS.Add(col.ColumnName)
        Next
        Return RS
    End Function
    Public Function GetDataTableAllColumnNames(DT As DataView) As List(Of String)
        Return GetDataTableAllColumnNames(DT.Table)
    End Function
    Public Function GetDataRowFromDataTableWithIDOnlyFirst(ByRef DT_This As DataTable, IDValue As Integer, Optional IDName As String = "ID") As DataRow
        If IsNothing(DT_This.Columns(IDName)) Then Throw New Exception("传入的datatable没有" & IDName)
        For i As Integer = 0 To DT_This.Rows.Count - 1
            If IsDBNull(DT_This.Rows(i)("ID")) = False Then
                If DT_This.Rows(i)("ID") = IDValue Then
                    Return DT_This.Rows(i)
                End If
            End If
        Next
        Return Nothing
    End Function
    Public Sub DeleteDataTablePointIDs(ByRef DT_This As DataTable, IDs() As Integer, Optional IDName As String = "ID")
        If IsNothing(DT_This.Columns(IDName)) Then Throw New Exception("传入的datatable没有" & IDName)
        For Each ThisID In IDs
            For i As Integer = DT_This.Rows.Count - 1 To 0 Step -1
                If IsDBNull(DT_This.Rows(i)("ID")) = False Then
                    If DT_This.Rows(i)("ID") = ThisID Then
                        DT_This.Rows.RemoveAt(i)
                    End If
                End If
            Next
        Next
    End Sub
    Public Sub DeleteDataTableRowFilter(ByRef DT_This As DataTable, RowFilter As String)
        Using DV_This As DataView = New DataView(DT_This, RowFilter, "", DataViewRowState.CurrentRows)
            For i As Integer = DV_This.Count - 1 To 0 Step -1
                DT_This.Rows.Remove(DV_This(i).Row)
            Next
        End Using
    End Sub
    Public Function ChangeDateTostring_With_FromatStr(ByVal Date_This As Object, Optional FormatStr As String = "yyyy-MM-dd HH:mm:ss") As String
        Try
            Return ChangeDateTostring_With_FromatStr(CDate(Date_This), FormatStr)
        Catch ex As Exception
            Return ""
        End Try
    End Function
    Public Function ChangeDateTostring_With_FromatStr(ByVal Date_This As Date, Optional FormatStr As String = "yyyy-MM-dd HH:mm:ss") As String
        Try
            Return CDate(Date_This).ToString(FormatStr)
        Catch ex As Exception
            Return ""
        End Try

    End Function
    Public Function GetDataTableColumnsStr(DT_This As DataTable) As String
        If IsNothing(DT_This) Then Return ""
        Dim RS As String = ""
        For i As Integer = 0 To DT_This.Columns.Count - 1
            RS += DT_This.Columns(i).ColumnName
        Next
        Return RS
    End Function
    Public Function Create特殊DataTable(Optional RowCount As Integer = 1000) As DataTable
        Return Create特殊DataTable(10, RowCount)
    End Function

    Public Function Create特殊DataTable(ColumnCount As Integer, RowCount As Integer) As DataTable
        Dim DT_THis As New DataTable
        DT_THis.Columns.Add("ID", GetType(Integer))
        DT_THis.Columns.Add("Style", GetType(Integer))
        DT_THis.Columns.Add("Style1", GetType(Integer))
        DT_THis.Columns.Add("Value", GetType(Double))
        DT_THis.Columns.Add("Date", GetType(Date))
        For i As Integer = 0 To ColumnCount - 1
            DT_THis.Columns.Add("这是" & i + 1)
        Next
        Dim addstr As New List(Of String)
        For i As Integer = 0 To RowCount - 1
            addstr.Clear()
            addstr.Add(i)
            addstr.Add(i Mod 10)
            addstr.Add(i Mod 3)
            addstr.Add(i * Rnd() * 10000)
            addstr.Add(Now + TimeSpan.FromDays(i * Rnd() * 700))
            For j As Integer = 0 To ColumnCount - 1
                addstr.Add(String.Format(Rnd() * 100000, "0.00"))
            Next
            DT_THis.Rows.Add(addstr.ToArray)
        Next
        Return DT_THis
    End Function
    Private Function JK(ByRef GB() As Byte) As Integer
        Dim RI As Integer = GB.Length
        For i As Integer = 0 To GB.Length - 1
            If GB(i) = 0 Then
                RI -= 1
            End If
        Next
        Return RI
    End Function
    Public Function FormatLengthString(_S As String, WCount As Integer) As String
        Dim SG() = System.Text.Encoding.Unicode.GetBytes(_S)
        Dim MCount As Integer = JK(SG)
        Dim AddCount As Integer = WCount - MCount
        If AddCount > 0 Then
            Return _S & New String(" ", AddCount)
        Else
            Return _S
        End If
    End Function
    Public Function Is_Datatable是否结构相同(DT_参照 As DataTable, DT_对象 As DataTable, Optional IS_可以是包含关系 As Boolean = False)

        If IsNothing(DT_参照) Then Return False
        If IsNothing(DT_对象) Then Return False
        If IS_可以是包含关系 = True Then If DT_参照.Columns.Count <> DT_对象.Columns.Count Then Return False
        For i As Integer = 0 To DT_对象.Columns.Count - 1
            If IsNothing(DT_参照.Columns(DT_对象.Columns(i).ColumnName)) Then
                Return False
            Else
                If DT_参照.Columns(DT_对象.Columns(i).ColumnName).GetType IsNot DT_对象.Columns(i).GetType Then
                    Return False
                End If
            End If
        Next
        Return True
    End Function
    Public Function Is_Datatable是否名称相同(DT_参照 As DataTable, DT_对象 As DataTable, Optional IS_可以是包含关系 As Boolean = False)
        If IsNothing(DT_参照) Then Return False
        If IsNothing(DT_对象) Then Return False
        If IS_可以是包含关系 = True Then If DT_参照.Columns.Count <> DT_对象.Columns.Count Then Return False
        For i As Integer = 0 To DT_对象.Columns.Count - 1
            If IsNothing(DT_参照.Columns(DT_对象.Columns(i).ColumnName)) Then
                Return False
            End If
        Next
        Return True
    End Function
    Public Function StringDLL_切掉字符串_前(S_来源 As String, S_需要切掉的字符 As String, Optional B_必须开始于第一字符 As Boolean = True) As String
        Dim StartIndex As Integer = InStr(S_来源, S_需要切掉的字符)
        Dim CutCOunt As Integer = S_需要切掉的字符.Length
        If StartIndex = 1 Then
            Return Mid(S_来源, StartIndex + CutCOunt)
        ElseIf StartIndex = 0 Then
            Return S_来源
        Else
            If B_必须开始于第一字符 = True Then
                Return S_来源
            Else
                Return Mid(S_来源, 1, StartIndex - 1) & Mid(S_来源, StartIndex + CutCOunt)
            End If
        End If
    End Function
    Public Function StringDLL_切掉字符串_后(S_来源 As String, S_需要切掉的字符 As String, Optional B_必须结束于最后一字符 As Boolean = True) As String
        Dim StartIndex As Integer = InStrRev(S_来源, S_需要切掉的字符)
        Dim AllCount As Integer = S_来源.Length
        Dim CutCOunt As Integer = S_需要切掉的字符.Length
        If StartIndex = 0 Then
            Return S_来源
        ElseIf AllCount - CutCOunt + 1 = StartIndex Then
            Return Mid(S_来源, 1, StartIndex - 1)
        Else
            If B_必须结束于最后一字符 = True Then
                Return S_来源
            Else
                Return Mid(S_来源, 1, StartIndex - 1) & Mid(S_来源, StartIndex + CutCOunt)
            End If
        End If
    End Function

    ''' <summary>
    ''' 将nothing和null转换为""
    ''' </summary>
    ''' <param name="OB"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CaseDBNullToString(OB As Object, Optional IfDateFormatString As String = "yyy-MM-dd HH:mm:ss") As String
        If IsNothing(OB) Then Return ""
        If IsDBNull(OB) Then Return ""
        If OB.GetType Is GetType(Date) Then
            Return ChangeDateTostring_With_FromatStr(OB, IfDateFormatString) ' ChangeDateTostring(OB, IfDateReutrnTime)
        Else
            Return OB.ToString
        End If
    End Function
    Public Function CaseDBNullToAppointDataType(OB As Object, DataType As Type) As Object
        Select Case True
            Case DataType Is GetType(Date)
                If IsNothing(OB) Then Return Nothing
                If IsDBNull(OB) Then Return Nothing
                Try
                    Return CDate(OB)
                Catch ex As Exception
                    Return Nothing
                End Try
            Case DataType Is GetType(String)
                If IsNothing(OB) Then Return ""
                If IsDBNull(OB) Then Return ""
                If OB.GetType Is GetType(Date) Then
                    Return ChangeDateTostring(OB)
                Else
                    Return OB.ToString
                End If
            Case DataType Is GetType(Integer)
                Try
                    Return CInt(OB)
                Catch ex As Exception
                    Return CInt(0)
                End Try
            Case DataType Is GetType(Double)
                Try
                    Return CDbl(OB)
                Catch ex As Exception
                    Return CDbl(0)
                End Try
            Case DataType Is GetType(Decimal)
                Try
                    Return CDec(OB)
                Catch ex As Exception
                    Return CDec(0)
                End Try
            Case DataType Is GetType(Single)
                Try
                    Return CSng(OB)
                Catch ex As Exception
                    Return CSng(0)
                End Try
            Case DataType Is GetType(Int16)
                Try
                    Return CInt(OB)
                Catch ex As Exception
                    Return CInt(0)
                End Try
            Case DataType Is GetType(Long)
                Try
                    Return CLng(OB)
                Catch ex As Exception
                    Return CLng(0)
                End Try
            Case Else
                Throw New Exception("无法返回未定义的数据类型:" & DataType.ToString)
        End Select

    End Function
#Region "DataTableColumnAdd"
    Public Function DataTableColumnsAdd_ParamArray(ByRef _DT As DataTable, ByVal ParamArray _ColumnNames() As String)
        Return DataTableColumnsAdd_ParamArray(_DT, GetType(String), _ColumnNames)
    End Function
    Public Function DataTableColumnsAdd_ParamArray(ByRef _DT As DataTable, ByVal _ColumnType As Type, ByVal ParamArray _ColumnNames() As String)
        For i As Integer = 0 To _ColumnNames.Count - 1
            DataTableColumnAdd(_DT, _ColumnNames(i), _ColumnType, -1)
        Next
        Return True
    End Function
    Public Function DataTableColumnsAdd(ByRef _DT As DataTable, ByVal _ColumnNames() As String, ByVal _ColumnType As Type)
        For i As Integer = 0 To _ColumnNames.Count - 1
            DataTableColumnAdd(_DT, _ColumnNames(i), _ColumnType, -1)
        Next
        Return True
    End Function
    Public Function DataTableColumnsAdd(ByRef _DT As DataTable, ByVal _ColumnNames() As String)
        DataTableColumnsAdd(_DT, _ColumnNames, GetType(System.String))
        Return True
    End Function
    'Public Function DataTableColumnsAdd(ByRef _DT As DataTable, ByVal _ColumnNames() As String, ByVal _ColumnType As Type)
    '    For i As Integer = 0 To _ColumnNames.Count - 1
    '        DataTableColumnAdd(_DT, _ColumnNames(i), _ColumnType, -1)
    '    Next
    '    Return True
    'End Function
    Public Function DataTableColumnAdd(ByRef _DT As DataTable, ByVal _ColumnName As String, ByVal _ColumnType As Type)
        Return DataTableColumnAdd(_DT, _ColumnName, _ColumnType, -1)
    End Function
    Public Function DataTableColumnAdd(ByRef _DT As DataTable, ByVal _ColumnName As String)
        Return DataTableColumnAdd(_DT, _ColumnName, GetType(System.String), -1)
    End Function
    Public Function DataTableColumnAdd(ByRef _DT As DataTable, ByVal _ColumnName As String, ByVal _ColumnType As Type,
                                        SetOrdinal As String) As Boolean
        If SetOrdinal <> "" Then
            Return DataTableColumnAdd(_DT, _ColumnName, _ColumnType, _DT.Columns(SetOrdinal).Ordinal)
        Else
            Return DataTableColumnAdd(_DT, _ColumnName, _ColumnType, -1)
        End If
    End Function
    Public Function DataTableColumnAdd(ByRef _DT As DataTable, ByVal _ColumnName As String, ByVal _ColumnType As Type, SetOrdinal As Integer) As Boolean
        Dim myex As Exception = Nothing
        Try
            If IsNothing(_DT) Then Return False
            If IsNothing(_DT.Columns(_ColumnName)) Then
                _DT.Columns.Add(_ColumnName, _ColumnType)
                Return True
            Else
                Return True
            End If
        Catch ex As Exception
            myex = ex
            Return False
        Finally
            If IsNothing(myex) = False Then
                Throw myex
            Else
                If SetOrdinal <> -1 Then
                    _DT.Columns(_ColumnName).SetOrdinal(SetOrdinal)
                End If
            End If
        End Try
    End Function
#End Region

    Public Function ReplaceStr_单引号转义(ByVal Sourcestring As String) As String
        If IsNothing(Sourcestring) Then Return ""
        If IsDBNull(Sourcestring) Then Return ""
        Dim rs As String = Sourcestring
        rs = rs.Replace("'", "''")
        Return rs
    End Function
    Public Function ReplaceStr_单引号转下划线(ByVal Sourcestring As String) As String
        Dim rs As String = Sourcestring
        rs = rs.Replace("'", "_")
        Return rs
    End Function
    Public Function IniDataviewWithDataTable(ByRef DV As DataView, DT As DataTable,
                                              Optional RowFilter As String = "", Optional Sort As String = "") As DataView
        If IsNothing(DV) Then
            Return New DataView(DT, RowFilter, Sort, DataViewRowState.CurrentRows)
        Else
            DV.RowFilter = RowFilter
            DV.Sort = Sort
            Return DV
        End If
    End Function
    ''' <summary>
    ''' 获取某月的天数
    ''' </summary>
    ''' <param name="M"></param>
    ''' <param name="Y"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getLastDay(ByVal M As Integer, ByVal Y As Integer) As String
        Select Case M
            Case 1, 3, 5, 7, 8, 10, 12
                Return "31"
            Case 2
                If Y Mod 4 = 0 Then
                    Return "29"
                Else
                    Return "28"
                End If
            Case Else
                Return "30"
        End Select
    End Function
    ''' <summary>
    ''' 将日期装换为字符串
    ''' </summary>
    ''' <param name="Date_This">日期格式</param>
    ''' <param name="IsHaveTime">是否含有时分秒</param>
    ''' <param name="IsHaveDay">是否含有天(IsHaveTime=false才有效)</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ChangeDateTostring(ByVal Date_This As Object, Optional IsHaveTime As Boolean = True, Optional IsHaveDay As Boolean = True, Optional IsOnlyShowTime As Boolean = False) As String
        If IsNothing(Date_This) = True Then
            Return ""
        End If
        If IsDBNull(Date_This) = True Then
            Return ""
        End If
        If Date_This.GetType Is GetType(Date) Then
            If IsOnlyShowTime Then
                Dim ThisDate As Date = Date_This
                Return String.Format(ThisDate.Hour, "00") & ":" & String.Format(ThisDate.Minute, "00") & ":" & String.Format(ThisDate.Second, "00")
            Else
                If IsHaveTime = True Then
                    Return String.Format(Date_This.Year, "0000") & "-" & String.Format(Date_This.Month, "00") & "-" & String.Format(Date_This.Day, "00") & " " & String.Format(Date_This.Hour, "00") & ":" & String.Format(Date_This.Minute, "00") & ":" & String.Format(Date_This.Second, "00")
                Else
                    If IsHaveDay = True Then
                        Return String.Format(Date_This.Year, "0000") & "-" & String.Format(Date_This.Month, "00") & "-" & String.Format(Date_This.Day, "00")
                    Else
                        Return String.Format(Date_This.Year, "0000") & "-" & String.Format(Date_This.Month, "00")
                    End If
                End If
            End If
        ElseIf Date_This.GetType Is GetType(String) Then
            Return Date_This
        Else
            Try
                Return Date_This.ToString
            Catch ex As Exception
                Return ""
            End Try
        End If
    End Function
    Public Function DLL_合并数组(Arr1() As String, Arr2() As String, Optional OrderArr() As String = Nothing) As String()
        If IsNothing(Arr1) And IsNothing(Arr2) = False Then Return Arr2
        If IsNothing(Arr2) And IsNothing(Arr1) = False Then Return Arr1
        If IsNothing(Arr1) And IsNothing(Arr2) Then Return {}
        Dim RS = Arr1.ToList
        For j As Integer = 0 To Arr2.Count - 1
            Dim 标记_1中有 As Boolean = False
            For i As Integer = 0 To Arr1.Count - 1
                If Arr2(j) = Arr1(i) Then
                    标记_1中有 = True
                    Exit For
                End If
            Next
            If 标记_1中有 = False Then
                RS.Add(Arr2(j))
            End If
        Next
        '重新排序
        If IsNothing(OrderArr) Then
            Return RS.ToArray
        Else
            Return DLL_数组重新排序(RS.ToArray, OrderArr)
        End If
    End Function
    Public Function DLL_数组重新排序(RS() As String, OrderArr() As String) As String()
        Dim RSlist As New List(Of String)
        '先调整排序
        For Each item As String In OrderArr
            Dim 标记_列表中包含 As Boolean = False
            For Each RSitem In RS
                If item = RSitem Then
                    标记_列表中包含 = True
                    Exit For
                End If
            Next
            If 标记_列表中包含 Then
                RSlist.Add(item)
            End If
        Next
        '将剩下的加入到列表中
        For Each RSitem In RS
            Dim 标记_列表中包含 As Boolean = False
            For Each item In OrderArr
                If RSitem = item Then
                    标记_列表中包含 = True
                    Exit For
                End If
            Next
            If 标记_列表中包含 = False Then
                RSlist.Add(RSitem)
            End If
        Next
        Return RSlist.ToArray
    End Function
#Region "Dll_ColumnNames"
    ''' <summary>
    ''' 将dt列转为数组
    ''' </summary>
    ''' <param name="ColumnName"></param>
    ''' <param name="_DataView"></param>
    ''' <param name="OrderValue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Dll_ColumnNames(ByVal ColumnName As String, ByRef _DataView() As DataView, OrderValue() As String) As String()
        Dim RS() = Dll_ColumnNames(ColumnName, _DataView)
        Return DLL_数组重新排序(RS, OrderValue)
    End Function
    ''' <summary>
    ''' 将dt列转为数组
    ''' </summary>
    ''' <param name="ColumnName"></param>
    ''' <param name="_DataRows"></param>
    ''' <param name="OrderValue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Dll_ColumnNames(ByVal ColumnName As String, ByRef _DataRows() As DataRow, OrderValue() As String) As String()
        Dim RS() = Dll_ColumnNames(ColumnName, _DataRows)
        Return DLL_数组重新排序(RS, OrderValue)
    End Function
    ''' <summary>
    ''' 将dt列转为数组
    ''' </summary>
    ''' <param name="ColumnName"></param>
    ''' <param name="_DataRows"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Dll_ColumnNames(ByVal ColumnName As String, ByRef _DataRows() As DataRow) As String()
        Dim ReturnAll As New List(Of String)

        For i As Integer = 0 To _DataRows.Count - 1
            Dim Names = DCM.ChangeDateTostring(_DataRows(i)(ColumnName))
            Dim sign = False
            For j As Integer = 0 To ReturnAll.Count - 1
                If ReturnAll(j) = Names Then
                    sign = True
                    Exit For
                End If
            Next j
            If sign = False Then
                ReturnAll.Add(Names)
            End If
        Next i
        Return ReturnAll.ToArray
    End Function
    ''' <summary>
    ''' 将dt列转为数组
    ''' </summary>
    ''' <param name="ColumnName"></param>
    ''' <param name="_DataView"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Dll_ColumnNames(ByVal ColumnName As String, ByRef _DataView() As DataView) As String()
        Dim ReturnAll As New List(Of String)
        For Each dv In _DataView
            dv.Sort = ColumnName & " asc"
            For i As Integer = 0 To dv.Count - 1
                Dim Names = DCM.ChangeDateTostring(dv(i)(ColumnName))
                Dim sign = False
                For j As Integer = 0 To ReturnAll.Count - 1
                    If ReturnAll(j) = Names Then
                        sign = True
                        Exit For
                    End If
                Next j
                If sign = False Then
                    ReturnAll.Add(Names)
                End If
            Next i
        Next
        Return ReturnAll.ToArray
    End Function
    ''' <summary>
    ''' 将dt列转为数组
    ''' </summary>
    ''' <param name="ColumnName"></param>
    ''' <param name="_DataView"></param>
    ''' <param name="OrderValue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Dll_ColumnNames(ByVal ColumnName As String, ByRef _DataView As DataView, OrderValue() As String, IsNeedSord As Boolean) As String()
        Dim RS() = Dll_ColumnNames(ColumnName, _DataView, IsNeedSord)
        Return DLL_数组重新排序(RS, OrderValue)
    End Function
    ''' <summary>
    ''' 将dt列转为数组
    ''' </summary>
    ''' <param name="ColumnName"></param>
    ''' <param name="_DataView"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Dll_ColumnNames(ByVal ColumnName As String, ByRef _DataView As DataView, IsNeedSord As Boolean) As String()
        Dim sign As Boolean
        Dim Names As String
        Dim i As Integer, j As Integer
        Dim ReturnAll As New List(Of String)
        If IsNeedSord Then
            Dim Str_Sort_Old As String = _DataView.Sort
            _DataView.Sort = ColumnName & " asc"
            For i = 0 To _DataView.Count - 1
                Names = DCM.ChangeDateTostring(_DataView(i)(ColumnName))
                sign = False
                For j = 0 To ReturnAll.Count - 1
                    If ReturnAll(j) = Names Then
                        sign = True
                        Exit For
                    End If
                Next j
                If sign = False Then
                    ReturnAll.Add(Names)
                End If
            Next i
            '修复原来的排序方式
            _DataView.Sort = Str_Sort_Old
        Else
            For i = 0 To _DataView.Count - 1
                Names = DCM.ChangeDateTostring(_DataView(i)(ColumnName))
                sign = False
                For j = 0 To ReturnAll.Count - 1
                    If ReturnAll(j) = Names Then
                        sign = True
                        Exit For
                    End If
                Next j
                If sign = False Then
                    ReturnAll.Add(Names)
                End If
            Next i
        End If
        Return ReturnAll.ToArray
    End Function
    ''' <summary>
    ''' 将dt列转为数组
    ''' </summary>
    ''' <param name="Array"></param>
    ''' <param name="ChangeOneToFirst"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Dll_ColumnNames_ChageArrayOnetoFirst(Array() As String, ChangeOneToFirst As String) As String()
        If Array.Length = 0 Then Return Array
        Dim NewArray(Array.Length - 1) As String
        Dim IsFind As Boolean = False
        NewArray(0) = ChangeOneToFirst
        Dim NowIndex As Integer = 1
        For i As Integer = 0 To Array.Length - 1
            If Array(i) <> ChangeOneToFirst Then
                NewArray(NowIndex) = Array(i)
                NowIndex += 1

            Else
                IsFind = True
            End If
        Next
        If IsFind = True Then
            Return NewArray
        Else
            Return Array
        End If
    End Function
#End Region
    '根据Table创建tv菜单
    '''' <summary>
    '''' 原TV_Add_TongYong
    '''' </summary>
    '''' <param name="ColumnName"></param>
    '''' <param name="ThisTable"></param>
    '''' <param name="ThisTreeNode"></param>
    '''' <param name="ImageIndex_Main"></param>
    '''' <param name="ImageIndex_Child"></param>
    '''' <remarks></remarks>
    'Public Sub TVNodeAdd_DataTable(ByVal ColumnName As String, ByRef ThisTable As Data.DataTable, ByRef ThisTreeNode As TreeNode,
    '                           Optional ByRef ImageIndex_Main As Integer = 0, Optional ByRef ImageIndex_Child As Integer = 0) '创建Treeview菜单
    '    Dim Names_All = Dll_ColumnNames(ColumnName, ThisTable.DefaultView)
    '    '创建主节点
    '    Dim NewTNode As New TreeNode
    '    NewTNode.Name = ColumnName
    '    NewTNode.Text = ColumnName
    '    NewTNode.ImageIndex = ImageIndex_Main
    '    ThisTreeNode.Nodes.Add(NewTNode)

    '    For i = 0 To Names_All.Length - 1
    '        If Trim(Names_All(i)) <> "" Then
    '            Dim CN As New TreeNode
    '            CN.Text = Names_All(i)
    '            CN.Name = Names_All(i)
    '            CN.ImageIndex = ImageIndex_Child
    '            ThisTreeNode.Nodes(ThisTreeNode.Nodes.Count - 1).Nodes.Add(CN)
    '        Else
    '            Dim CN As New TreeNode
    '            CN.Text = "(空)"
    '            CN.Name = "(空)"
    '            CN.ImageIndex = ImageIndex_Child
    '            ThisTreeNode.Nodes(ThisTreeNode.Nodes.Count - 1).Nodes.Add(CN)
    '        End If
    '    Next
    'End Sub
    ''根据数组创建tv菜单
    '''' <summary>
    '''' 原TV_Add_FromArray
    '''' </summary>
    '''' <param name="FirstName"></param>
    '''' <param name="SecondArray"></param>
    '''' <param name="ThisTree"></param>
    '''' <remarks></remarks>
    'Public Sub TVNodeAdd_Array(ByVal FirstName As String, ByRef SecondArray() As String, ByRef ThisTree As TreeNode)
    '    '创建主节点
    '    Dim NewTNode As New TreeNode
    '    NewTNode.Name = FirstName
    '    NewTNode.Text = FirstName
    '    ThisTree.Nodes.Add(NewTNode)
    '    '子节点
    '    For i = 0 To SecondArray.Length - 1
    '        If Trim(FirstName) <> "" Then
    '            ThisTree.Nodes(ThisTree.Nodes.Count - 1).Nodes.Add(New TreeNode(SecondArray(i)))
    '        Else
    '            ThisTree.Nodes(ThisTree.Nodes.Count - 1).Nodes.Insert(0, New TreeNode("(空)"))
    '        End If
    '    Next
    'End Sub
    Public Function HeBingFilterstring_And(ByVal FS1 As String, ByVal FS2 As String, Optional ByVal FS3 As String = "") As String
        Dim Rs As String = ""
        If FS1 <> "" Then Rs = "(" & FS1 & ")"
        If Rs = "" Then
            If FS2 <> "" Then
                Rs = "(" & FS2 & ")"
            End If
        Else
            If FS2 <> "" Then
                Rs = Rs & " and (" & FS2 & ")"
            End If
        End If

        If Rs = "" Then
            If FS3 <> "" Then
                Rs = "(" & FS3 & ")"
            End If
        Else
            If FS3 <> "" Then
                Rs = Rs & " and (" & FS3 & ")"
            End If
        End If
        Return Rs
    End Function
    Public Function HeBingFilterstring_Or(ByVal FS1 As String, ByVal FS2 As String, Optional ByVal FS3 As String = "") As String
        Dim Rs As String = ""
        If FS1 <> "" Then Rs = "(" & FS1 & ")"
        If Rs = "" Then
            If FS2 <> "" Then
                Rs = "(" & FS2 & ")"
            End If
        Else
            If FS2 <> "" Then
                Rs = Rs & " Or (" & FS2 & ")"
            End If
        End If

        If Rs = "" Then
            If FS3 <> "" Then
                Rs = "(" & FS3 & ")"
            End If
        Else
            If FS3 <> "" Then
                Rs = Rs & " Or (" & FS3 & ")"
            End If
        End If
        Return Rs
    End Function


    Public Function GetColumnIndexWithNameForDataTable(ByVal Name As String, ByRef DT As Data.DataTable) As Integer
        For i As Integer = 0 To DT.Columns.Count - 1
            If DT.Columns(i).ColumnName = Name Then
                Return i
            End If
        Next
        GetColumnIndexWithNameForDataTable = -1
        Throw New Exception("无法定位" & Name & ",请确认输入是否正确!")
    End Function
End Module